<?php
namespace app\logic;

class Install
{
    private $dsn;
    private $user;
    private $pass;

    public function install($param)
    {
        extract($param);
        // 数据库账号
        $this->user = $dbuser;
        // 数据库密码
        $this->pass = $dbpass;
        // dsn
        $this->dsn = "mysql:host=$host:$port;";
        // 连接
        $db = $this->connect();
        if (!$db) {
            $db = null;
            return [config('status.server'), "数据库信息有误"];
        }
        // 创建数据表
        $this->createDataBase($db, $dbname);
        // 更改 dsn
        $this->dsn = $this->dsn . "dbname=$dbname;";
        $db = $this->connect();
        $create_table = $this->createTable($db, $prefix, $username, $password);
        if($create_table !== true) {
            $db = null;
            return $create_table;
        }

        // 更新配置文件
        $this->updateDbConfig($host, $dbname, $dbuser, $dbpass, $port, $prefix);

        $db = null;
        if($this->isInstall()) {
            return [config('status.success'), "安装成功"];
        }
        return [config('status.fail'), "安装失败, 请刷新重试"];
    }

    /**
     * 数据库 PDO 连接
     * @return \PDO|bool
     */
    private function connect()
    {
        if(empty($this->dsn) || empty($this->user) || empty($this->pass)){
            return false;
        }
        $db = null;
        try{
            $db = new \PDO($this->dsn, $this->user, $this->pass);
        } catch(\PDOException $e) {
            return false;
        }

        return $db ?: false;
    }

    /**
     * 新建数据库
     * @param $db
     * @param $dbname
     * @return array|bool
     */
    private function createDataBase($db, $dbname)
    {
        if(!$db) {
            return false;
        }
        try{
            $sql = 'CREATE DATABASE IF NOT EXISTS '.$dbname.' DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci';
            $db->exec($sql);
        } catch(\PDOException $e) {
            return false;
        }
        return true;
    }

    /**
     * 创建表及数据
     * @param $prefix
     * @param string $username 管理员用户名
     * @param string $password 管理员密码
     * @return array|bool
     */
    private function createTable($db, $prefix, $username, $password)
    {
        if(!$db) {
            return [config('status.server'), "数据库配置错误"];
        }
        // 构建 SQL 语句
        $sql = str_replace(
            ['{{$prefix}}', '{{$username}}', '{{$password}}', '{{$create_time}}'],
            [$prefix, $username, md5($password), date('Y-m-d H:i:s', time())],
            @file_get_contents(root_path("extend". DS . "tpl". DS ."install") . "data.sql")
        );
        // 拆分 SQL 语句
        $sql_array = preg_split("/;[\r\n]+/", $sql);
        foreach ($sql_array as $k => $v) {
            if(empty($v)) {
                continue;
            }
            // 判断是否为建表语句
            if (substr($v, 0, 12) == 'CREATE TABLE') {
                // 截取当前创建表名
                $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $v);
                $msg = "创建数据表{$name}";
                $res = $db->query($v);
                if ($res === false) {
                    return [config('status.server'), $msg."失败"];
                }
            } else {
                $res = $db->query($v);
                if ($res === false) {
                    dd(1);
                    return [config('status.server'), "数据插入失败 " . $v];
                }
            }
        }
        return true;
    }

    /**
     * 更新数据库配置文件
     * @param $dbname
     * @param $dbuser
     * @param $dbpass
     * @param $port
     * @param $prefix
     */
    private function updateDbConfig($host, $dbname, $dbuser, $dbpass, $port, $prefix)
    {
        $content = str_replace(
            ['{{$host}}', '{{$name}}', '{{$user}}', '{{$pass}}', '{{$port}}', '{{$prefix}}'],
            [$host, $dbname, $dbuser, $dbpass, $port, $prefix],
            @file_get_contents(root_path("extend". DS . "tpl". DS ."install") . "database.tpl")
        );
        @mkdir(root_path()."config/", 0755, true);
        @file_put_contents(root_path()."config/database.php", $content);
        @touch(public_path().'install.lock');
    }

    /**
     * 是否安装
     * @return bool
     */
    public function isInstall()
    {
        return file_exists(public_path().'install.lock');
    }
}